package com.drinks.yiniang.ui.widget.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.drinks.yiniang.R;
import com.drinks.yiniang.entity.common.RadarEntity;
import com.hansen.library.utils.ColorUtils;
import com.hansen.library.utils.CommonUtils;
import com.hansen.library.utils.ScreenSizeUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author han
 * @date 2019/11/13
 */
public class RadarMapView extends View {
    //默认大小
    private final int DEFAULT_SIZE;
    //多边形点的个数
    private int mPolygonCount = 6;
    //蜘蛛层级
    private int mLayerCount = 5;
    //多边形均等分角度
    private float mAngle = (float) (Math.PI * 2 / mPolygonCount);
    //网格最大半径
    private float mRadius;
    //中心x
    private float mCenterX;
    //中心y
    private float mCenterY;
    //数据最大值
    private float mMaxValue = 1;
    private int mTextHeight;
    private int mMinTextWidth;
    private int mTextPadding = 25;
    private float mRadarRatio = 0.6f;
    private float mRadarRadiusRatio = 0.7f;

    private int mRadarMapTextSize;

    private RectF mTextRectF = new RectF();

    //雷达区画笔
    private Paint mPolygonPaint;
    //文本画笔
    private Paint mTextPaint;
    //文本背景
    private Paint mTextBackground;

    private Path mPolygonPath;

    private List<RadarEntity> mRadarList;

    public RadarMapView(Context context) {
        this(context, null);
    }

    public RadarMapView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RadarMapView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        DEFAULT_SIZE = ScreenSizeUtils.dp2px(context, 200);

        initAttr(attrs);
        init();
    }

    private void initAttr(AttributeSet attrs) {
        mRadarMapTextSize = ScreenSizeUtils.sp2Px(getContext(), 12);

        mTextHeight = ScreenSizeUtils.dp2px(getContext(), 20);
        mMinTextWidth = ScreenSizeUtils.dp2px(getContext(), 28);

        if(attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.RadarMapViewStyles);

            mRadarRatio = a.getFloat(R.styleable.RadarMapViewStyles_radarMapRatio, 0.6f);
            mRadarRadiusRatio = a.getFloat(R.styleable.RadarMapViewStyles_radarMapRadiusRatio, 0.7f);

            mRadarMapTextSize = a.getDimensionPixelSize(R.styleable.RadarMapViewStyles_radarMapTextSize, mRadarMapTextSize);
            mTextHeight = a.getDimensionPixelOffset(R.styleable.RadarMapViewStyles_radarMapTextHeight, mTextHeight);
            mMinTextWidth = a.getDimensionPixelOffset(R.styleable.RadarMapViewStyles_radarMapMinWidth, mMinTextWidth);

            a.recycle();
        }
    }

    private void init() {
        mPolygonPaint = new Paint();
        mPolygonPaint.setAntiAlias(true);
        mPolygonPaint.setStrokeWidth(3);

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setColor(Color.BLACK);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setTextSize(mRadarMapTextSize);

        mTextBackground = new Paint();
        mTextBackground.setAntiAlias(true);
        mTextBackground.setStrokeWidth(1);
        mTextBackground.setStyle(Paint.Style.FILL);
        mTextBackground.setStrokeCap(Paint.Cap.ROUND);
        mTextBackground.setColor(ColorUtils.getColorById(getContext(), R.color.color_f2f2f2));

        mPolygonPath = new Path();

        if (isInEditMode()) {
            List<RadarEntity> lst = new ArrayList<>();

            lst.add(new RadarEntity("维度1", 50));
            lst.add(new RadarEntity("维度2", 20));
            lst.add(new RadarEntity("维度3", 30));
            lst.add(new RadarEntity("维度4", 40));
            lst.add(new RadarEntity("维度5", 50));
            lst.add(new RadarEntity("维度6", 60));

            setRadarData(lst);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = measureWidth(widthMeasureSpec);
        int height = (int) (width * mRadarRatio);

        setMeasuredDimension(measureWidth(widthMeasureSpec), height);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        // 外接圆半径为宽高除(2*0.7)
        mRadius = Math.min(w, h) / 2 * mRadarRadiusRatio;

        // 初始化X和Y
        mCenterX = w / 2f;
        mCenterY = h / 2f;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mRadarList != null) {
            drawPolygonsArea(canvas);
            //绘制多边形
            drawPolygons(canvas);
            drawLines(canvas);
            drawRegion(canvas);
            drawTextArea(canvas);
        }
    }

    private int measureWidth(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        //设置一个默认值，就是这个View的默认宽度为1，这个看我们自定义View的要求
        int result = DEFAULT_SIZE;

        if (specMode == MeasureSpec.EXACTLY) {//相当于我们设置为match_parent或者为一个具体的值
            result = specSize;
        }

        return result;
    }

    //绘制正多边形背景
    private void drawPolygonsArea(Canvas canvas) {
        mPolygonPaint.setStyle(Paint.Style.FILL);
        mPolygonPaint.setColor(ColorUtils.getColorById(getContext(), R.color.color_fff6f5));

        float x;
        float y;

        for (int j = 0; j < mPolygonCount; j++) {//绘制每一层的多边形
            x = (float) (mRadius * Math.cos(mAngle * j));
            y = (float) (mRadius * Math.sin(mAngle * j));

            if (j == 0) {
                mPolygonPath.moveTo(mCenterX + x, mCenterY + y);
            } else {
                //根据半径，计算出蜘蛛丝上每个点的坐标
                mPolygonPath.lineTo(mCenterX + x, mCenterY + y);
            }
        }

        //闭合路径
        mPolygonPath.close();
        canvas.drawPath(mPolygonPath, mPolygonPaint);
    }

    //绘制正多边形
    private void drawPolygons(Canvas canvas) {
        mPolygonPaint.setStyle(Paint.Style.STROKE);
        mPolygonPaint.setColor(ColorUtils.getColorById(getContext(), R.color.color_ffbdb9));
        mPolygonPaint.setAlpha(255);

        float layerDis = mRadius / mLayerCount;
        float x, y;

        for (int i = 1; i <= mLayerCount; i++) {//蜘蛛层级

            mPolygonPath.reset();

            //当前半径
            float currentRadius = layerDis * i;

            for (int j = 0; j < mPolygonCount; j++) {//绘制每一层的多边形

                x = (float) (currentRadius * Math.cos(mAngle * j));
                y = (float) (currentRadius * Math.sin(mAngle * j));

                if (j == 0) {
                    mPolygonPath.moveTo(mCenterX + x, mCenterY + y);
                } else {
                    //根据半径，计算出蜘蛛丝上每个点的坐标
                    mPolygonPath.lineTo(mCenterX + x, mCenterY + y);
                }
            }

            //闭合路径
            mPolygonPath.close();
            canvas.drawPath(mPolygonPath, mPolygonPaint);
        }
    }

    /**
     * 绘制正多边形
     */
    private void drawLines(Canvas canvas) {
        mPolygonPaint.setStyle(Paint.Style.STROKE);
        mPolygonPaint.setColor(ColorUtils.getColorById(getContext(), R.color.color_ffbdb9));
        mPolygonPaint.setAlpha(255);

        float x, y;

        for (int i = 0; i < mPolygonCount; i++) {//蜘蛛层级

            mPolygonPath.reset();
            mPolygonPath.moveTo(mCenterX, mCenterY);

            x = (float) (mRadius * Math.cos(mAngle * i));
            y = (float) (mRadius * Math.sin(mAngle * i));

            //根据半径，计算出蜘蛛丝上每个点的坐标
            mPolygonPath.lineTo(mCenterX + x, mCenterY + y);

            canvas.drawPath(mPolygonPath, mPolygonPaint);
        }
    }

    /**
     * 绘制区域
     */
    private void drawRegion(Canvas canvas) {
        mPolygonPaint.setStyle(Paint.Style.FILL);
        mPolygonPaint.setColor(ColorUtils.getColorById(getContext(), R.color.color_ef3024));
        mPolygonPaint.setAlpha(125);

        mPolygonPath.reset();

        float x;
        float y;

        for (int i = 0; i < mPolygonCount; i++) {//绘制每一层的多边形
            x = (float) (mRadius * Math.cos(mAngle * i) * (mRadarList.get(i).getValue() / mMaxValue));
            y = (float) (mRadius * Math.sin(mAngle * i) * (mRadarList.get(i).getValue() / mMaxValue));

            if (i == 0) {
                mPolygonPath.moveTo(mCenterX + x, mCenterY + y);
            } else {
                //根据半径，计算出蜘蛛丝上每个点的坐标
                mPolygonPath.lineTo(mCenterX + x, mCenterY + y);
            }
        }

        //闭合路径
        mPolygonPath.close();
        canvas.drawPath(mPolygonPath, mPolygonPaint);
    }

    //画文字
    private void drawTextArea(Canvas canvas) {
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();

        float fontHeight = fontMetrics.descent - fontMetrics.ascent;
        float x;
        float y;
        float tempTopY, tempBottomY;

        for (int i = 0; i < mPolygonCount; i++) {
            //计算最外侧蜘蛛丝上每个点的坐标
            x = (float) (mCenterX + (mRadius + fontHeight / 2) * Math.cos(mAngle * i));
            y = (float) (mCenterY + (mRadius + fontHeight / 2) * Math.sin(mAngle * i));

            if (mRadarList.get(i).getTitle() == null) {
                mRadarList.get(i).setTitle("--");
            }

            float dis = mTextPaint.measureText(mRadarList.get(i).getTitle());

            if (mAngle * i == 0) {
                drawTextRoundRectF(canvas, x, y - mTextHeight / 2, x + dis + mTextPadding, y + mTextHeight / 2);
                drawText(canvas, mRadarList.get(i).getTitle());
            } else if (Math.PI - mAngle * i >= -0.1 && Math.PI - mAngle * i <= 0.1) {
                drawTextRoundRectFByRight(canvas, x - dis - mTextPadding * 2, y - mTextHeight / 2, x, y + mTextHeight / 2);
                drawText(canvas, mRadarList.get(i).getTitle());
            } else if (mAngle * i >= 0 && mAngle * i <= Math.PI / 2) {//第4象限
                drawTextRoundRectF(canvas, x, y, x + dis, y + mTextHeight);
                drawText(canvas, mRadarList.get(i).getTitle());
            } else if (mAngle * i >= Math.PI / 2 && mAngle * i <= Math.PI) { //第3象限
                drawTextRoundRectF(canvas, x - dis - mTextPadding * 2, y, x - mTextPadding * 2, y + mTextHeight);
                drawText(canvas, mRadarList.get(i).getTitle());
            } else if (mAngle * i >= Math.PI && mAngle * i <= 3 * Math.PI / 2) { //第2象限
                drawTextRoundRectF(canvas, x - dis - mTextPadding * 2, y - mTextHeight, x - mTextPadding, y);
                drawText(canvas, mRadarList.get(i).getTitle());
            } else if (mAngle * i >= 3 * Math.PI / 2 && mAngle * i <= Math.PI * 2) {//第1象限
                drawTextRoundRectF(canvas, x, y - mTextHeight, x + dis, y);
                drawText(canvas, mRadarList.get(i).getTitle());
            }
        }
    }

    private void drawText(Canvas canvas, String text) {
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        float distance = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;

        float baseline = mTextRectF.centerY() + distance;

        canvas.drawText(text, mTextRectF.centerX(), baseline, mTextPaint);
    }

    private void drawTextRoundRectF(Canvas canvas, float l, float t, float r, float b) {
        mTextRectF.left = l;
        mTextRectF.top = t;
        mTextRectF.right = r - l >= mMinTextWidth + mTextPadding * 2 ? r + mTextPadding * 2 : l + mMinTextWidth + mTextPadding * 2;
        mTextRectF.bottom = b;

        canvas.drawRoundRect(mTextRectF, mTextHeight / 2, mTextHeight / 2, mTextBackground);
    }

    private void drawTextRoundRectFByRight(Canvas canvas, float l, float t, float r, float b) {
        mTextRectF.left = r - l >= mMinTextWidth + mTextPadding * 2 ? r - mTextPadding * 2 : r - mMinTextWidth - mTextPadding * 2;
        mTextRectF.top = t;
        mTextRectF.right = r;
        mTextRectF.bottom = b;

        canvas.drawRoundRect(mTextRectF, mTextHeight / 2, mTextHeight / 2, mTextBackground);
    }


    //设置几边形，**注意：设置几边形需要重新计算圆心角**
    public void setRadarData(List<RadarEntity> list) {
        if (CommonUtils.isEmptyList(list)) {
            return;
        }

        mRadarList = list;

        this.mMaxValue = 1;

        for (RadarEntity entity : mRadarList) {
            this.mMaxValue = Math.max(this.mMaxValue, entity.getValue());
        }

        this.mPolygonCount = mRadarList.size();

        mAngle = (float) (Math.PI * 2 / this.mPolygonCount);

        invalidate();
    }

    //设置几边形，**注意：设置几边形需要重新计算圆心角**
    public void setRadarEvaluateData(List<RadarEntity> list, float maxValue) {
        if (CommonUtils.isEmptyList(list)) {
            return;
        }

        mRadarList = list;

        this.mMaxValue = maxValue;

        this.mPolygonCount = mRadarList.size();

        mAngle = (float) (Math.PI * 2 / this.mPolygonCount);

        invalidate();
    }

    //设置层数
    public void setLayerCount(int layerCount) {
        this.mLayerCount = layerCount;

        invalidate();
    }
}
